// Package interface_service_v1
// @Author zhongxc
// @Date 2024/7/26 15:00:00
// @Desc
package interface_service_v1

import (
	"context"
	"fmt"
	"github.com/jinzhu/copier"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/emptypb"
	"strings"
	"time"
	"vben-admin/pkg/dao"
	"vben-admin/pkg/model"
	"vben-admin/pkg/repository"
	"vben-admin/pkg/svc"
	interfaceServiceV1 "vben-grpc-common/vben-admin/types/interface.service.v1"
)

type InterfaceService struct {
	svcCtx *svc.ServiceContext
	interfaceServiceV1.UnimplementedInterfaceServiceServer
	interfaceDao repository.InterfaceRepo
}

func NewInterfaceService(svcCtx *svc.ServiceContext) *InterfaceService {
	return &InterfaceService{
		svcCtx:       svcCtx,
		interfaceDao: dao.NewInterfaceDao(svcCtx.Db),
	}
}

// CreateInterface
// @Description: 创建接口
// @receiver i
// @param ctx
// @param in
// @return *emptypb.Empty
// @return error
func (i *InterfaceService) CreateInterface(ctx context.Context, in *interfaceServiceV1.CreateInterfaceRequest) (*emptypb.Empty, error) {
	// 参数检查
	if strings.TrimSpace(in.Name) == "" {
		return nil, status.Error(codes.InvalidArgument, "接口名称不能为空")
	}
	if strings.TrimSpace(in.Url) == "" {
		return nil, status.Error(codes.InvalidArgument, "接口地址不能为空")
	}

	// 接口名称、地址重复检测
	inter, err := i.interfaceDao.FindByNameOrUrl(ctx, in.Name, "")
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil {
		return nil, status.Error(codes.AlreadyExists, "接口名称已存在")
	}
	inter, err = i.interfaceDao.FindByNameOrUrl(ctx, "", in.Url)
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil {
		return nil, status.Error(codes.AlreadyExists, "接口地址已存在")
	}

	// 组装参数
	var interfaceModel model.InterfaceModel
	_ = copier.Copy(&interfaceModel, in)
	interfaceModel.CreatedAt.Time = time.Now()
	interfaceModel.CreatedAt.Valid = true

	// 保存数据
	err = i.interfaceDao.CreateInterface(ctx, &interfaceModel)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("接口创建失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	return &emptypb.Empty{}, nil
}

// UpdateInterface
// @Description: 接口更新
// @receiver i
// @param ctx
// @param in
// @return *emptypb.Empty
// @return error
func (i *InterfaceService) UpdateInterface(ctx context.Context, in *interfaceServiceV1.UpdateInterfaceRequest) (*emptypb.Empty, error) {
	// 参数检查
	if in.Id <= 0 {
		return nil, status.Error(codes.InvalidArgument, "ID不能为空")
	}
	if strings.TrimSpace(in.Name) == "" {
		return nil, status.Error(codes.InvalidArgument, "接口名称不能为空")
	}
	if strings.TrimSpace(in.Url) == "" {
		return nil, status.Error(codes.InvalidArgument, "接口地址不能为空")
	}

	// 接口名称、地址重复检测
	inter, err := i.interfaceDao.FindByNameOrUrl(ctx, in.Name, "")
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil && inter.Id != in.Id {
		return nil, status.Error(codes.AlreadyExists, "接口名称已存在")
	}
	inter, err = i.interfaceDao.FindByNameOrUrl(ctx, "", in.Url)
	if err != nil {
		return nil, status.Error(codes.Internal, err.Error())
	}
	if inter != nil && inter.Id != in.Id {
		return nil, status.Error(codes.AlreadyExists, "接口地址已存在")
	}

	// 参数组装
	data := make(map[string]interface{})
	data["name"] = in.Name
	data["url"] = in.Url
	data["method"] = in.Method
	data["description"] = in.Description
	data["updated_by"] = in.UpdatedBy
	data["updated_at"] = time.Now()

	// 保存数据
	err = i.interfaceDao.UpdateInterface(ctx, in.Id, data)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("接口更新失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}
	return &emptypb.Empty{}, nil
}

// DeleteInterface
// @Description: 接口删除
// @receiver i
// @param ctx
// @param in
// @return *emptypb.Empty
// @return error
func (i *InterfaceService) DeleteInterface(ctx context.Context, in *interfaceServiceV1.DeleteInterfaceRequest) (*emptypb.Empty, error) {
	// 参数检查
	if len(in.Ids) == 0 {
		return nil, status.Error(codes.InvalidArgument, "ID不能为空")
	}

	// 数据删除
	err := i.interfaceDao.DeleteInterface(ctx, in.Ids)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("接口删除失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	return &emptypb.Empty{}, nil
}

// GetInterfaceList
// @Description: 接口列表
// @receiver i
// @param ctx
// @param in
// @return *interfaceServiceV1.InterfaceListResponse
// @return error
func (i *InterfaceService) GetInterfaceList(ctx context.Context, in *interfaceServiceV1.GetInterfaceListRequest) (*interfaceServiceV1.InterfaceListResponse, error) {
	// 参数检查
	if in.Page == 0 {
		in.Page = 1
	}
	if in.Page > 100 {
		in.Page = 100
	}
	if in.PageSize == 0 {
		in.PageSize = 10
	}
	if in.PageSize > 100 {
		in.PageSize = 100
	}

	// 数据查询
	list, err := i.interfaceDao.GetInterfaceList(ctx, in.Name, in.Url, in.Page, in.PageSize)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("接口列表获取失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	// 列表数据转换
	var interfaceList []*interfaceServiceV1.InterfaceData
	for _, item := range list["data"].([]*model.InterfaceModel) {
		var interfaceData interfaceServiceV1.InterfaceData
		if item.UpdatedAt.Valid && !item.UpdatedAt.Time.IsZero() {
			interfaceData.UpdatedAt = item.UpdatedAt.Time.Format(time.DateTime)
		}
		if item.CreatedAt.Valid && !item.CreatedAt.Time.IsZero() {
			interfaceData.CreatedAt = item.CreatedAt.Time.Format(time.DateTime)
		}
		_ = copier.Copy(&interfaceData, item)
		interfaceList = append(interfaceList, &interfaceData)
	}

	// 数据响应
	return &interfaceServiceV1.InterfaceListResponse{
		TotalCount: list["totalCount"].(int64),
		Page:       list["page"].(int64),
		TotalPage:  list["totalPage"].(int64),
		Limit:      list["pageSize"].(int64),
		Data:       interfaceList,
	}, nil
}

// GetInterfaceInfo
// @Description: 接口详情获取
// @receiver i
// @param ctx
// @param in
// @return *interfaceServiceV1.InterfaceResponse
// @return error
func (i *InterfaceService) GetInterfaceInfo(ctx context.Context, in *interfaceServiceV1.GetInterfaceInfoRequest) (*interfaceServiceV1.InterfaceResponse, error) {
	// 参数检查
	if in.Id <= 0 {
		return nil, status.Error(codes.InvalidArgument, "ID不能为空")
	}

	info, err := i.interfaceDao.GetInterfaceInfo(ctx, in.Id)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("接口详情获取失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, err.Error())
	}

	if info == nil {
		return nil, status.Error(codes.NotFound, "数据不存在")
	}

	var interfaceResp interfaceServiceV1.InterfaceResponse
	_ = copier.Copy(&interfaceResp, info)

	return &interfaceResp, nil
}

func (i *InterfaceService) GetAll(ctx context.Context, in *emptypb.Empty) (*interfaceServiceV1.InterfaceAllListResponse, error) {

	list, err := i.interfaceDao.GetAll(ctx)
	if err != nil {
		i.svcCtx.ZapLog.Error(fmt.Sprintf("接口列表获取失败, err: %s\n", err.Error()))
		return nil, status.Error(codes.Internal, "接口列表获取失败")
	}

	var interfaceList = make([]*interfaceServiceV1.InterfaceData, 0)
	for _, item := range list {
		var interfaceData interfaceServiceV1.InterfaceData
		_ = copier.Copy(&interfaceData, item)
		if item.CreatedAt.Valid && !item.CreatedAt.Time.IsZero() {
			interfaceData.CreatedAt = item.CreatedAt.Time.Format(time.DateTime)
		}
		if item.UpdatedAt.Valid && !item.CreatedAt.Time.IsZero() {
			interfaceData.UpdatedAt = item.UpdatedAt.Time.Format(time.DateTime)
		}
		interfaceList = append(interfaceList, &interfaceData)
	}

	return &interfaceServiceV1.InterfaceAllListResponse{
		Data: interfaceList,
	}, nil
}
